import { ColumnConfig } from "./ColumnConfig";
let columns = ColumnConfig.defaults;
export class Column {
  /**
   * 构造函数
   * @param {string} title 列标题
   * @param {string} key 列关联键值
   */
  constructor(title, key) {
    this._vue = ColumnConfig.Vue;
    this.properties = {
      width: columns.default.width,
      sortable: true
    };
    if (title) {
      this.properties.title = title;
    }
    if (key) {
      this.properties.key = key;
    }
  }

  type(value) {
    this.properties.type = value;
    return this;
  }

  /**
   * @param {string} title 列头显示文字
   */
  title(title) {
    this.properties.title = title;
    return this;
  }

  /**
   * @param {string} key 对应列内容的字段名
   */
  key(key) {
    this.properties.key = key;
    return this;
  }

  /**
   * @param {Number} value 列宽
   */
  width(value) {
    this.properties.width = value;
    return this;
  }

  /**
   * @param {Number} value 最小列宽
   */
  minWidth(value) {
    this.properties.minWidth = value;
    return this
  }

  /**
   * @param {number} value 最大列宽
   */
  maxWidth(value) {
    this.properties.maxWidth = value;
    return this;
  }

  /**
   * @param {string} value 对齐方式，可选值为 left 左对齐、right 右对齐和 center 居中对齐
   */
  align(value) {
    this.properties.align = value;
    return this;
  }

  /**
   * @param {string} value 列是否固定在左侧或者右侧，可选值为 left 左侧和 right 右侧
   */
  fixed(value) {
    this.properties.fixed = value;
    return this;
  }

  /**
   * 传入两个参数，第一个是 h，第二个为对象，包含 row、column 和 index，分别指当前行数据，当前列数据，当前行索引，详见示例。
   * @param {Function} fn 自定义渲染列，使用 Vue 的 Render 函数。
   */
  render(fn) {
    this.properties.render = fn;
    return this;
  }

  /**
   * @param {boolean} value 对应列是否可以排序，如果设置为 custom，则代表用户希望远程排序，需要监听 Table 的 on-sort-change 事件  Boolean | 'custom'
   * @param {Function} method 自定义排序使用的方法，接收三个参数 a 、 b 和 type，当设置 sortable: true 时有效。type 值为 asc 和 desc
   */
  sort(value = true, method = undefined) {
    this.properties.sortable = value;
    this.properties.sortMethod = method;
    return this;
  }

  hidden(value) {
    this.properties.hidden = value;
    return this;
  }

  /**
   * 开启后，文本将不换行，超出部分显示为省略号，并用 Tooltip 组件显示完整内容
   */
  tooltip(width) {
    this.properties.tooltip = true;
    const defaults = {
      width: 200
    };
    let column = Object.assign(defaults, columns.tooltip);
    return this.sort(false).width(width || column.width);
  }

  /**
   * 开启后，文本将不换行，超出部分显示为省略号
   */
  ellipsis() {
    this.properties.ellipsis = true;
    return this.sort(false);
  }

  /**
   * @param {Function} fn 自定义序号  Function，参数 row 为当前行内
   */
  index(fn) {
    const defaults = {
      width: 80,
      title: "索引",
      align: "center"
    };
    const column = Object.assign(defaults, columns.index);
    return this
      .sort(false)
      .width(column.width)
      .align(column.align)
      .title(column.title)
      .type("index");
  }

  selection(fixed = "left") {
    const defaults = {
      align: "center",
      width: 80,
      fixed: "left"
    };
    const column = Object.assign(defaults, columns.selection, { fixed });
    return this
      .type("selection")
      .width(column.width)
      .align(column.align)
      .fixed(column.fixed);
  }

  format(fn = (value, row) => { }) {
    const execute = (params) => {
      let primaryValue;
      if (this.properties.key) {
        primaryValue = params.row[this.properties.key];
      }
      return fn(primaryValue, params.row);
    };
    this.properties.render = (h, params) => h("span", execute(params));
    return this.align("center").width(110);
  }

  detail(detailKey, routeName) {
    const properties = this.properties;
    const defaults = {
      width: 250
    };
    const column = Object.assign(defaults, columns.detail);
    return this
      .width(column.width)
      .render(function (h, params) {
        const name = params.row[properties.key];
        if (name) {
          // 未设置路由名称则显示为纯文本
          const tagName = routeName ? 'router-link' : 'span';
          const primaryKey = params.row[detailKey];
          const props = {
            to: { name: routeName, params: { id: primaryKey } }
          }
          return h(tagName, { props }, name);
        } else {
          return ``;
        }
      });
  }

  dict(dictionary) {
    const defaults = {
      width: 150
    };
    const column = Object.assign(defaults, columns.dict);
    return this
      .format(v => this._vue.$dict.convert(dictionary, v))
      .width(column.width)
      .sort(true, undefined);
  }

  filter(filterName, params) {
    return this
      .format(v => this._vue.$options.filters[filterName](v, params))
      .width(200)
      .sort(true);
  }

  datetime(format) {
    const defaults = {
      format: 'yyyy-MM-dd HH:mm:ss',
      width: 200
    };
    const column = Object.assign(defaults, columns.datetime);
    return this.filter('utc', format || column.format).width(column.width);
  }

  slot() {
    let params = this.build();
    return Object.assign(params, {
      title: this.properties.title,
      slot: this.properties.key
    });
  }

  build() {
    let resizable = false;
    if (this.properties.width) {
      resizable = true;
    }
    return { ...this.properties, resizable };
  }
}
